package multi_thread.advanced.blocking_queue;

import multi_thread.master.tools.ExchangerExample;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author Cheng Jun
 * Description: SynchronousQueue 其实是一个对接通道。线程B 从里面取数据，线程A 往里面放数据才有用。
 * 如果没线程在阻塞地取数据，放入就没有效果 或 报错 或 阻塞
 * 不能使用 peek 方法
 * @version 1.0
 * @date 2022/5/16 14:00
 * @see ExchangerExample
 */
public class SynchronousQueueExample {
    public static void main(String[] args) throws InterruptedException {
        SynchronousQueue<Integer> intSynchronousQueue = new SynchronousQueue<>();
        TakeThread takeThread = new TakeThread(intSynchronousQueue);
        takeThread.start();
        TimeUnit.SECONDS.sleep(1);
        try {
            // 如果没有线程在等待着取数据，put 数据就会阻塞
            intSynchronousQueue.put(1);
            // offer(E e, long timeout, TimeUnit unit) 带阻塞时间的入列操作
            intSynchronousQueue.offer(2, 2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    static class TakeThread extends Thread {
        private SynchronousQueue<Integer> intSynchronousQueue;

        @Override
        public void run() {
            while (true) {
                try {
                    // poll(long timeout, TimeUnit unit) 带阻塞时间的出列
                    // 阻塞式出列操作
                    System.out.println("intSynchronousQueue.take(): " + intSynchronousQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        TakeThread(SynchronousQueue<Integer> intSynchronousQueue) {
            this.intSynchronousQueue = intSynchronousQueue;
        }
    }

}
